#!/usr/bin/python3
# coding:utf-8
import os
import threading
import subprocess
import time
from queue import Queue
import platform
from tkinter import filedialog
import tkinter
import msvcrt
import re


# 初始化变量，ipSucess为存储可以ping通的IP列表，Work_Thread为后台工作进程数，ipQueue为执行命令的队列
ipSuccess = []
ipFail = []
Work_Thread = 50
ipQueue = Queue()


def main():

    root = tkinter.Tk()  # 创建一个Tkinter.Tk()实例
    root.withdraw()  # 将Tkinter.Tk()实例隐藏
    try:
        file_path = filedialog.askopenfilename(
            title=u'选择文件', filetypes=[('TXT', '*.txt'), ('All Files', '*')],  initialdir=(os.path.dirname(os.path.realpath(__file__))))
        start_time = time.time()
        if len(file_path) != 0:
            files = open(file_path)
            comp = re.compile(
                r'^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}')
            for line in files.readlines():
                line = line.strip('\n')
                if comp.match(line):
                    ipQueue.put(line)
            files.close()

        else:
            SystemExit()

        # 灰色， '\033[90m' + str(i) + '\033[0m'
        # 红色,  '\033[91m' + str(i) + '\033[0m'
        # 绿色,  '\033[92m' + str(i) + '\033[0m'

        # 初始化线程池，并多线程调用pingIP函数
        threads = []
        for i in range(Work_Thread):
            thread = threading.Thread(target=pingIp)
            thread.start()
            threads.append(thread)
        for thread in threads:
            thread.join()

        # 将可以ping通的IP地址从ipsuccess列表取出并渲染成绿色
        print("Batch Ping Tools V0.1: BY WJJ\nList of Alive host:")
        for i in ipSuccess:
            # i = '\033[92m'+i+'\033[0m'
            if (platform.system()) == "Windows":
                print("%s\tUP" % i)
            else:
                print("\033[92m%s\tUP\033[0m" % i)
        print("\nList of Down host:")
        for i in ipFail:
            # i = '\033[91m'+i+'\033[0m'
            # print("%s\tDwon" % i)
            if (platform.system()) == "Windows":
                print("%s\tDown" % i)
            else:
                print("\033[91m%s\tDown\033[0m" % i)

        # 打印提示信息，包括在线主机数和脚本执行时间
        time_info = format(time.time() - start_time, '.2f')
        total_num = str(len(ipSuccess)+len(ipFail))
        up_num = str(len(ipSuccess))
        down_num = str(len(ipFail))

        run_info = "Total:"+total_num+" UP:"+up_num + \
            " Down:"+down_num+" Time:" + time_info+"s"
        print('\n' + run_info, flush=True)

        # 释放无用资源
        ipSuccess.clear()
        ipFail.clear()
    except:
        print("打开文件出错!")


def pingIp():
    while not ipQueue.empty():
        ip = ipQueue.get()
        if (platform.system()) == "Windows":
            # 如果为linux或macos，此处cmd应为'ping -c 2 -W 5',命令行参数不太一致
            cmd = 'ping -n 2 -w 5 %s' % ip
            # 如果为linux或macos，此处subprocess.call参数需在后面补充shell=True
            # DETACHED_PROCESS = 0x00000008
            # p = subprocess.call(cmd, stdout=subprocess.PIPE,
            #                     stderr=subprocess.PIPE, creationflags=DETACHED_PROCESS)

            p = subprocess.call(cmd, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
            # print(ip, True if res == 0 else False)
            # 如果返回值为0，代表ping命令正确返回，此处仅简单判断状态，后续可读取通道信息，获取延时数据，针对延时时长渲染其他的颜色
            if p == 0:
                ipSuccess.append(ip)
            else:
                ipFail.append(ip)
        else:
            cmd = 'ping -c 2 -W 5 %s' % ip
            p = subprocess.call(cmd, stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE, shell=True)
            if p == 0:
                ipSuccess.append(ip)
            else:
                ipFail.append(ip)

            # 从这里开始执行
if __name__ == '__main__':
    main()
    print("Press 'Q' to exit...")
    while True:
        if ord(msvcrt.getch()) in [81, 113]:
            break
